# -*- coding:utf-8 -*-
"""
@Time : 2022/4/27 5:24 PM
@Author: xiaomi
@Des: 内容管理
"""
from app.common.common import write_access_log
from core.Response import success, fail, res_antd
from models.base import ModelPage, Category, ModelNews, Content, ModelPro
from schemas.backend import content
from core.Auth import create_access_token, check_permissions
from fastapi import Request, Query, APIRouter, Security, File, UploadFile
from config import settings
from typing import List
from tortoise.queryset import F
from schemas.base import BaseResp 
from tortoise.transactions import in_transaction
import logging

logger = logging.getLogger(__name__)

router = APIRouter()

@router.get("/page/{cate_id}", summary="单页详情", dependencies=[Security(check_permissions, scopes=["page_detail"])])
async def page_detail(cate_id: int):
    """
    单页详情
    :param cate_id:
    :return:
    """
    page = await ModelPage.get_or_none(cate=cate_id).values("content", "cate_id", "pageid", "piclist")
    if not page:
        return fail(msg="单页不存在")
    if page["piclist"]:
        page["piclist"] = page["piclist"].split(",")
    else:
        page["piclist"] = []
    return success(data=page)

@router.post("/page", summary="单页修改", response_model=BaseResp, dependencies=[Security(check_permissions, scopes=["update_page"])])
async def page_update(post: content.UpdatePageReq):
    """
    更新单页信息
    :param post:
    :return:
    """

    cate_check = await Category.get_or_none(pk=post.cate_id)
    if not cate_check:
        return fail(msg="栏目不存在")

    page_check = await ModelPage.get_or_none(cate=post.cate_id)
    if not page_check:
        await ModelPage.create(**post.model_dump())
        return success(msg="创建成功")
    
    await ModelPage.filter(cate=post.cate_id).update(content=post.content)
    return success(msg="更新成功!")

@router.get(
    "/category/tree",
    summary="栏目树",
    dependencies=[Security(check_permissions, scopes=["category_tree"])]
)
async def category_tree():
    """
    栏目树
    :return:
    """
    category_list = await Category.annotate(key=F("cate_id"), label=F("cate_name")).filter(cate_type__in=[-1, 1, 2, 3]).all().values("key", "parent_id", "label", "cate_type")
    for item in category_list:
        if item["cate_type"] == -1:
            item["path"] = '/backend/content/page.html?classid='+str(item["key"])
        if item["cate_type"] == 1:
            item["path"] = '/backend/content/news/list.html?classid='+str(item["key"])
        if item["cate_type"] == 2:
            item["path"] = '/backend/content/pro/list.html?classid='+str(item["key"])
        if item["cate_type"] == 3:
            item["path"] = '/backend/content/job/list.html?classid='+str(item["key"])
        if item["cate_type"] == 4:
            item["path"] = '/backend/content/case/list.html?classid='+str(item["key"])
    tree_data = cate_tree(category_list, 0)
    return success(data=tree_data)
    
def cate_tree(data, pid):
    """
    遍历栏目树
    :param data: rule[]
    :param pid: 父ID
    :return: list
    """
    result = []
    for item in data:
        if pid == item["parent_id"]:
            temp = cate_tree(data, item["key"])
            if len(temp) > 0:
                item["children"] = temp
            result.append(item)
    return result

@router.get("/news/list/{cate_id}", summary="新闻列表", dependencies=[Security(check_permissions, scopes=["news_list"])])
async def news_list(cate_id: int = 0):
    """
    新闻列表
    :param cate_id: 分类ID (0表示所有分类)
    :return: 包含新闻列表的响应
    """

    # 构建基础查询（使用Tortoise ORM的正确方法链）
    query = ModelNews.all().select_related("con")
    
    # 处理分类过滤（当cate_id > 0时进行过滤）
    if cate_id > 0:
        query = query.filter(con__category_id=cate_id)  # 注意使用实际的数据库字段名
    
    # 执行查询
    news_list = await query.order_by("-con__sort").values(
        "con__id",
        "newsid",
        "con__title",
        "con__pic",
        "con__ispic",
        "con__category__cate_name",
        "con__category__cate_id",
        "con__sort",
        "con__hots",
        "con__isnice",
        "con__istop",
        "con__islock",
        "content"
    )
    rep_data = []
    for news in news_list:
        rep_data.append({
            "id":news['con__id'],
            "title":news['con__title'],
            "pic":news['con__pic'],
            "ispic":news['con__ispic'],
            "cate_name":news['con__category__cate_name'],
            "cate_id":news['con__category__cate_id'],
            "content":news['content'],
            "sort":news['con__sort'],
            "hots":news['con__hots'],
            "isnice":news['con__isnice'],
            "istop":news['con__istop'],
            "islock":news['con__islock']
        })
    
    return success(data=rep_data)

@router.post("/news", summary="新闻添加", response_model=BaseResp, dependencies=[Security(check_permissions, scopes=["news_add"])])
async def news_add(post: content.AddNewsReq):
    """
    新闻添加
    :param post:
    :return:
    """
    try:
        async with in_transaction():  # 事务包裹
            # 1. 验证栏目是否存在
            cate_check = await Category.get_or_none(pk=post.cate_id)
            if not cate_check:
                return fail(msg="栏目不存在")

            # 2. 创建 Content 记录 (明确使用 category_id 或模型实例)
            content_data = await Content.create(
                title=post.title,
                category_id=post.cate_id,  # 或 category=cate_check
                sort=post.sort,
                istop=post.istop,
                isnice=post.isnice,
                islock=post.islock
            )

            # 3. 创建关联的 ModelNews
            await ModelNews.create(con=content_data, content=post.content)

            return success(msg="添加成功")
    except Exception as e:
        logger.error(f"新闻添加失败: {str(e)}", exc_info=True)
        return fail(msg="添加失败，请检查数据或稍后再试")

@router.put("/news", summary="新闻更新", response_model=BaseResp, dependencies=[Security(check_permissions, scopes=["news_update"])])
async def news_update(post: content.UpdateNewsReq):
    """
    新闻更新
    :param post:
    :return:
    """
    try:
        async with in_transaction():  # 事务包裹
            # 1. 验证栏目是否存在
            cate_check = await Category.get_or_none(pk=post.cate_id)
            if not cate_check:
                return fail(msg="栏目不存在")
            
             # 2. 获取要更新的内容
            content_check = await Content.get_or_none(id=post.id)
            if not content_check:
                return fail(msg="内容不存在")
    
            # 3. 更新新闻
            content_check.title=post.title
            content_check.category=cate_check
            content_check.sort=post.sort
            content_check.istop=post.istop
            content_check.isnice=post.isnice
            content_check.islock=post.islock
            content_check.pic=post.pic
            content_check.ispic=1 if post.pic else 0
            await content_check.save()

            if cate_check.cate_type == 1:  # 如果是新闻栏目，则更新内容
                await ModelNews.filter(con=content_check).update(content=post.content)
            return success(msg="更新成功")
    except Exception as e:
        logger.error(f"新闻更新失败: {str(e)}", exc_info=True)
        return fail(msg="更新失败，请检查数据或稍后再试")

@router.get("/product/list/{cate_id}", summary="产品列表", dependencies=[Security(check_permissions, scopes=["product_list"])])
async def pro_list(cate_id: int = 0):
    """
    产品列表
    :param cate_id: 分类ID (0表示所有分类)
    :return: 包含产品列表的响应
    """

    # 构建基础查询（使用Tortoise ORM的正确方法链）
    query = ModelPro.all().select_related("con")
    
    # 处理分类过滤（当cate_id > 0时进行过滤）
    if cate_id > 0:
        query = query.filter(con__category_id=cate_id)  # 注意使用实际的数据库字段名
    
    # 执行查询
    pro_list = await query.order_by("-con__sort").values(
        "con__id",
        "proid",
        "con__title",
        "con__pic",
        "con__ispic",
        "con__category__cate_name",
        "con__category__cate_id",
        "con__sort",
        "con__hots",
        "con__isnice",
        "con__istop",
        "con__islock",
        "content",
        "price",
        "piclist"
    )
    rep_data = []
    for pro in pro_list:
        rep_data.append({
            "id":pro['con__id'],
            "title":pro['con__title'],
            "pic":pro['con__pic'],
            "ispic":pro['con__ispic'],
            "cate_name":pro['con__category__cate_name'],
            "cate_id":pro['con__category__cate_id'],
            "content":pro['content'],
            "price":pro['price'],
            "piclist":pro['piclist'],
            "sort":pro['con__sort'],
            "hots":pro['con__hots'],
            "isnice":pro['con__isnice'],
            "istop":pro['con__istop'],
            "islock":pro['con__islock']
        })
    
    return success(data=rep_data)

@router.post("/product", summary="产品添加", response_model=BaseResp, dependencies=[Security(check_permissions, scopes=["product_add"])])
async def product_add(post: content.AddProReq):
    """
    产品添加
    :param post:
    :return:
    """
    try:
        async with in_transaction():  # 事务包裹
            # 1. 验证栏目是否存在
            cate_check = await Category.get_or_none(pk=post.cate_id)
            if not cate_check:
                return fail(msg="栏目不存在")

            # 2. 创建 Content 记录 (明确使用 category_id 或模型实例)
            content_data = await Content.create(
                title=post.title,
                category_id=post.cate_id,
                pic=post.pic,
                ispic=1 if post.pic else 0,
                sort=post.sort,
                istop=post.istop,
                isnice=post.isnice,
                islock=post.islock
            )

            # 3. 创建关联的 ModelNews
            await ModelPro.create(con=content_data, content=post.content, piclist=post.piclist, price=post.price)

            return success(msg="添加成功")
    except Exception as e:
        logger.error(f"新闻添加失败: {str(e)}", exc_info=True)
        return fail(msg="添加失败，请检查数据或稍后再试")

@router.put("/product", summary="产品更新", response_model=BaseResp, dependencies=[Security(check_permissions, scopes=["news_update"])])
async def pro_update(post: content.UpdateProReq):
    """
    产品更新
    :param post:
    :return:
    """
    try:
        async with in_transaction():  # 事务包裹
            # 1. 验证栏目是否存在
            cate_check = await Category.get_or_none(pk=post.cate_id)
            if not cate_check:
                return fail(msg="栏目不存在")
            
             # 2. 获取要更新的内容
            content_check = await Content.get_or_none(id=post.id)
            if not content_check:
                return fail(msg="内容不存在")
    
            # 3. 更新新闻
            content_check.title=post.title
            content_check.category=cate_check
            content_check.sort=post.sort
            content_check.istop=post.istop
            content_check.isnice=post.isnice
            content_check.islock=post.islock
            content_check.pic=post.pic
            content_check.ispic=1 if post.pic else 0
            await content_check.save()

            if cate_check.cate_type == 1:  # 如果是新闻栏目，则更新内容
                await ModelPro.filter(con=content_check).update(content=post.content, piclist=post.piclist, price=post.price)   
            return success(msg="更新成功")
    except Exception as e:
        logger.error(f"新闻更新失败: {str(e)}", exc_info=True)
        return fail(msg="更新失败，请检查数据或稍后再试")